package com.common.ui.recycleview.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import com.common.R;
import com.common.bean.InfoResult;
import com.common.ui.recycleview.PullLoadMoreRecyclerView;
import com.common.ui.recycleview.adapter.viewholder.FooterHolder;
import com.common.ui.recycleview.adapter.viewholder.HeaderHolder;
import com.common.ui.recycleview.base.ViewHolder;
import com.common.ui.recycleview.listener.DataStateListener;
import com.common.utils.Constants;
import java.util.ArrayList;
import java.util.List;

/**
 * [description about this class]
 * Recyclerview基础数据适配器(同一种数据类型,分页)
 * 使用过程中,真实的数据类型Bean应该是不同的,那么这里要引入泛型代表我们的Bean,
 * 内部通过一个List<T>代表我们的数据集合
 * @author jack
 */

public abstract class RecyclerviewBasicPageAdapter<T> extends RecyclerView.Adapter<ViewHolder>{

    /**
     * item 类型
     */
    public final static int TYPE_NORMAL = 0;//正常
    public final static int TYPE_HEADER = 1;//头部
    public final static int TYPE_FOOTER = 2;//底部
    public boolean isShowFooter = false;
    public boolean isShowHeader = false;
    private HeaderHolder headerHolder;
    private FooterHolder footerHolder;
    protected Context context;
    protected int layoutId;
    protected List<T> datas = new ArrayList<>();
    protected LayoutInflater inflater;
    public String operatorTxT = "down";//down下拉刷新 up加载更多
    public String timestamp = "";
    public Toast toast = null;
    private int footerState = 1;//1正在加载... 2加载失败,点击重新加载 3没有更多数据了!
    public PullLoadMoreRecyclerView pMRecyclerView;
    public DataStateListener dataStateListener;

    public RecyclerviewBasicPageAdapter(Context context, int layoutId) {
        this.context = context;
        inflater = LayoutInflater.from(context);
        this.layoutId = layoutId;
    }

    public RecyclerviewBasicPageAdapter(Context context, int layoutId,
                                        PullLoadMoreRecyclerView pullLoadMoreRecyclerView,
                                        DataStateListener dataStateListener) {
        this.context = context;
        inflater = LayoutInflater.from(context);
        this.layoutId = layoutId;
        this.pMRecyclerView = pullLoadMoreRecyclerView;
        this.dataStateListener = dataStateListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        if (viewType == TYPE_HEADER) {
            if(headerHolder == null){
                headerHolder = HeaderHolder.createViewHolder(this.context,parent, R.layout.header_layout);
            }
            return headerHolder;
        }else if(viewType == TYPE_FOOTER){
            if(footerHolder == null){
                footerHolder = FooterHolder.createViewHolder(this.context,parent, R.layout.footer_layout);
            }
            return footerHolder;
        }else if(viewType == TYPE_NORMAL){
            ViewHolder viewHolder = ViewHolder.createViewHolder(context,parent, layoutId);
            return viewHolder;
        }
        return null;

    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        int type = getItemViewType(position);
        if(type == TYPE_FOOTER){
            TextView textView = footerHolder.getView(R.id.loadMoreText);
            ProgressBar progressBar = footerHolder.getView(R.id.loadMoreProgressBar);
            LinearLayout loadMoreLayout = footerHolder.getView(R.id.loadMoreLayout);
            if(footerState==1){
                progressBar.setVisibility(View.VISIBLE);
                textView.setText(R.string.load_more_going);
            }else if(footerState==2){
                progressBar.setVisibility(View.GONE);
                textView.setText(R.string.load_more_failure);
                loadMoreLayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        pMRecyclerView.setFooterState(1);
                        pMRecyclerView.setPushRefreshing(true);
                        pMRecyclerView.getPullLoadMoreListener().onLoadMore();
                        pMRecyclerView.loadMore();
                    }
                });
            }else if(footerState==3){
                progressBar.setVisibility(View.GONE);
                textView.setText(R.string.no_more_data);
            }
        }
        if(type == TYPE_HEADER){

        }
        if (type == TYPE_NORMAL) {
            if(datas!=null && datas.size()>0){
                if(position<datas.size()){
                    convert(holder, datas.get(position),position);
                }
            }
        }
    }

    @Override
    public int getItemCount() {
        int count = datas != null ? datas.size() : 0;
        if (isShowFooter){
            count++;
        }
        if (isShowHeader){
            count++;
        }
        return count;
    }

    @Override
    public int getItemViewType(int position) {
        int headerPosition = 0;
        int footerPosition = getItemCount() - 1;
        if (headerPosition == position && isShowHeader) {
            return TYPE_HEADER;
        }
        if (footerPosition == position && isShowFooter) {
            return TYPE_FOOTER;
        }
        return TYPE_NORMAL;
    }

    /**
     * 增加数据
     * @param infos
     */
    public final void addDataSource(List<T> infos, InfoResult infoResult) {

        if(getOperatorTxT().equals("down")){
            pMRecyclerView.refreshFinish();
            if (this.datas == null || this.datas.size() == 0) {
                int state = infoResult.getState();
                if(state == Constants.NO_NET_NUMBER){
                    dataStateListener.onDataState(1);
                }else{
                    boolean flag = infoResult.isSuccess();
                    if(flag){
                        if(infos!=null && infos.size()>0){
                            dataStateListener.onDataState(4);
                            this.datas.addAll(infos);
                            notifyDataSetChanged();
                        }else{
                            dataStateListener.onDataState(2);
                        }
                    }else{
                        dataStateListener.onDataState(3);
                    }
                }
            }else
                {
                int state = infoResult.getState();
                if(state == Constants.NO_NET_NUMBER){
                    dataStateListener.onDataState(1);
                }else{
                    boolean flag = infoResult.isSuccess();
                    if(flag){
                        this.datas.clear();
                        this.datas.addAll(infos);
                        notifyDataSetChanged();
                    }
                }
            }
        }else{
            if(pMRecyclerView.getFooterState()!=3){
                pMRecyclerView.setMoreData();
                boolean flag = infoResult.isSuccess();
                if(flag){
                    if (infos == null || infos.size() == 0) {
                        pMRecyclerView.setFooterState(3);
                        pMRecyclerView.setNoMoreData();
                        footerState = 3;
                        notifyDataSetChanged();
                        showToast(context.getString(R.string.no_more_data));
                    }else{
                        this.datas.addAll(infos);
                        notifyDataSetChanged();
                    }
                }
            }
        }
    }

    /**
     * 列表添加一条数据时可以调用，伴有(默认)动画效果
     * @param t
     */
    public void addItem(T t) {
        if(t!=null){
            if(datas == null){
                return;
            }
            if(datas.size()==0){
                datas.add(0, t);
                notifyItemInserted(0);
            }else{
                int position = datas.size();
                datas.add(position, t);
                //列表position添加一条数据时可以调用，伴有(默认)动画效果
                notifyItemInserted(position);
            }
        }
    }

    /**
     *  列表position位置移除一条数据时调用，伴有动画效果
     * @param t
     */
    public void removeItem(T t) {
        if(t!=null){
            if(datas == null || datas.size()==0){
                return;
            } else{
                int position = datas.indexOf(t);
                datas.remove(position);
                notifyItemRemoved(position);
            }
        }
    }

    /**
     * 更新列表position位置上的数据可以调用
     * @param position
     */
    public void notifyItem(int position){
        notifyItemChanged(position);
    }

    /**
     * 列表fromPosition位置的数据移到toPosition位置时调用，伴有动画效果
     * 界面效果是交换了，但真实的数据集合没有交换,这里实现数据位置的交换
     * @param fromPosition
     * @param toPosition
     */
    public void moveItemMove(int fromPosition, int toPosition){
        if(datas == null){
            return;
        }
        if(datas.size()==0){
            return;
        }else{
            T tFrom = datas.get(fromPosition);
            T tTo = datas.get(toPosition);
            datas.set(fromPosition,tTo);
            datas.set(toPosition,tFrom);
            notifyItemMoved(fromPosition, toPosition);
        }
    }

    /**
     * 列表从positionStart位置到itemCount数量的列表项进行数据刷新
     * @param positionStart
     * @param itemCount
     */
    public void notifyItemLotSizeChange(int positionStart, int itemCount){
        notifyItemRangeChanged(positionStart, itemCount);
    }

    /**
     * 列表项批量添加数据时调用，伴有动画效果
     */
    public void addLotSizeItem(List<T> beans){
        if(beans != null && beans.size() > 0){
            if(datas == null){
                return;
            }
            if(datas.size()==0){
                datas.addAll(beans);
                notifyItemRangeInserted(0, datas.size());
            }else{
                int positionStart = datas.size();
                datas.addAll(beans);
                //列表从positionStart位置到itemCount数量的列表项批量添加数据时调用，伴有动画效果
                notifyItemRangeInserted(positionStart, datas.size());
            }
        }
    }

    /**
     * 列表从positionStart位置到itemCount数量的列表项批量删除数据时调用，伴有动画效果
     * @param positionStart
     * @param itemCount
     */
    public void notifyItemRangeRemove(int positionStart, int itemCount){
        if(datas == null){
            return;
        }
        if(datas.size()==0){
            return;
        }else{
            /**这里对positionStart itemCount只做了简单的判断,这里只做操作,
               具体的传值是否符合要求,根据自己的数据源发起调该方法着去处理
             */
            notifyItemRangeRemoved(positionStart, itemCount);
            if(itemCount<=0 || positionStart<=0){
                return;
            }else{
                for(int i = 0;i<itemCount;i++){
                    datas.remove(positionStart);
                }
            }
        }
    }

    /**
     * 重置adapter(下拉刷新用到)
     */
    public void reset(){
        operatorTxT = "down";
        timestamp = "";
    }

    public void showToast(String msg) {
        if (toast == null) {
            toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        } else {
            toast.setText(msg);
        }
        toast.show();
    }

    public void setLoadMore(){
        operatorTxT = "up";
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    public void setDataSource(List<T> datas)
    {
        this.datas = datas;
        notifyDataSetChanged();
    }

    public List<T> getDataSource()
    {
        return this.datas;
    }

    public abstract void convert(ViewHolder holder, T t,int position);

    public String getOperatorTxT() {
        return operatorTxT;
    }

    public void setOperatorTxT(String operatorTxT) {
        this.operatorTxT = operatorTxT;
    }

    public boolean isShowFooter() {
        return isShowFooter;
    }

    public void setShowFooter(boolean showFooter) {
        isShowFooter = showFooter;
        if(isShowFooter){
            pMRecyclerView.getRecyclerView().scrollToPosition(getItemCount());
        }
    }

    public boolean isShowHeader() {
        return isShowHeader;
    }

    public void setShowHeader(boolean showHeader) {
        isShowHeader = showHeader;
    }

    public int getFooterState() {
        return footerState;
    }

    public void setFooterState(int footerState) {
        this.footerState = footerState;
    }
}
